# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
"""
Tooltip for stack descriptions.
"""
__docformat__ = "restructuredtext en"
#_ = lambda x: x
import tkinter.ttk

from ..pilelib import InitialDealTalon
from .canvas import WindowItem
from . import constants as vcnst
from ..utillib.misc import Point

class _PileToolTips(object):
    """
    Create sequence of help tooltips for all unique piles in the curent game.
    """
    _canvas = _info = None

    def __call__(self, game):
        """
        Show pile tips on canvas.

         Set canvas and info values from given game. Call canvas item method
         with each unique pile to create the tip. Only InitialDealTalons which
         are never used after game start are skipped.

        .. \__call__(game:Game) -> None
        """
        if self.delete():
            return
        else:
            self._canvas = game.canvas
            self._info = {'group': game.s, 'ranks': game._RANKS_,
                          'suits': game._SUITS_, 'width': game.images.size.w}
            s_list = []
            for stack in game.allstacks:
                key = (stack.__class__.__name__, stack.cap['base_rank'],
                       stack.cap['base_suit'], stack.cap['dir'],)
                if key in s_list or isinstance(stack, InitialDealTalon):
                    continue
                s_list.append(key)
                self.__canvas_item(stack)

    def __canvas_item(self, stack):
        """
        Create window item for tip on canvas.

        Create a label with return of call stack tip method with given stack.
        Create window item for canvas with label.

        .. __canvas_item() -> None
        """
        width = self._info['width']
        label = tkinter.ttk.Label(self._canvas, text=self.__stack_tip(stack),
                          wraplength=width, style='npsTip.TLabel')
        label.pack()
        item = WindowItem(self._canvas, Point(stack.x + width / 2, stack.y),
                          window=label)
        item.bind('<ButtonPress>', callback=lambda e, i=item: i.raise_item())

    def delete(self):
        """
        Remove pile tip texts from canvas.

        Call canvas find with tag method to find tips. Call canvas delete method
        to remove items. Reset canvas and info values. Return success.

        .. delete() -> bool
        """
        if self._canvas is None:
            return False
        state = bool(self._canvas.find_withtag('WindowItem'))
        self._canvas.delete('WindowItem')
        self._canvas = self._info = None
        return state

    def __stack_tip(self, pile):
        """
        Create pile tip text.

        Join name of group from given pile group in game stacks and return from
        call pile help string method. When pile builds append its values of
        base rank and base suit capability.

        .. \__stack_tip(pile:Pile)
        """
        text = ''
        g_info = self._info['group']
        for name, group in ([_(g.title()), g_info[g]] for g in g_info):
            if ((isinstance(group, (list, tuple)) and pile in group) or
                pile is group):
                text = "{0}. {1}".format(name, pile._helpString)
                break
        if pile.cap['max_accept'] > 0:
            rank, suit = pile.cap['base_rank'], pile.cap['base_suit']
            text += "\nBase Card - {0} of {1}.".format(
                       self._info['ranks'].get(rank, rank + 1),
                       self._info['suits'].get(suit, ''))
        return text.strip()

PileToolTips = _PileToolTips()